using System;
using System.Collections.Generic;
using Edge.Business.Entities;
using Edge.Business.Security;
using Edge.Common;
using Edge.Common.ComponentModel;
using Edge.Common.ComponentModel.Notification;
using Edge.Common.Services;
using Edge.Common.Utils;
using Edge.DAL.Common;
using Edge.DAL.Managers;
using NHibernate;
using NHibernate.Expression;
using Shop.Business.Domain.Catalog;
using Shop.Business.Domain.Customers;

namespace Shop.DAL.Managers
{
    class CategoryManager : AbstractManager<Category, int, Customer>, ICategoryManager
    {
        public ICollection<Category> Find(FetchOptions fetchOptions, CategoryFilter filter)
        {
            ICriteria criteria = CreateCriteria(fetchOptions);
            AddRestrictions(criteria, filter);
            return criteria.List<Category>();
        }

        public int Count(CategoryFilter filter)
        {
            ICriteria criteria = CreateCriteria();
            AddRestrictions(criteria, filter);
            criteria.SetProjection(Projections.RowCount());
            return (int)criteria.List()[0];
        }

        private void AddRestrictions(ICriteria criteria, CategoryFilter filter)
        {
            if (filter.ParentCategory!= null)
                criteria.Add(Expression.Eq("ParentCategory", filter.ParentCategory));
            if (!StringUtils.IsBlankOrNull(filter.GetText()) && !(filter.GetText().Trim().Equals("")))
            {
                criteria.Add(Expression.Disjunction()
                                 .Add(Expression.Like("Name", filter.GetText().Trim() + "%"))
                                 .Add(Expression.Like("Description", "%" + filter.GetText().Trim() + "%"))
                    );
            }
        }

        public ICollection<Category> GetCategories(int? id)
        {
            IList<Category> ret = null;
                if (id != null && id != 0)
                {
                    CategoryFilter filter = new CategoryFilter();
                    filter.ParentCategory = Load(Convert.ToInt32(id));
                    ret = (IList<Category>)Find(FetchOptions.All, filter);
                }
                else
                {
                    using (IDalOperation op = CreateLoadOperation())
                    {
                        ICriteria criteria = CreateCriteria();
                        criteria.Add(Expression.IsNull("ParentCategory"));
                        ret = criteria.List<Category>();
                        op.Commit();
                    }
                }
            return ret;
        }

        public ICollection<NavigationItem> ConvertToNavigation(ICollection<Category> categories)
        {
            ICollection<NavigationItem> ret = new List<NavigationItem>();
            foreach (Category cat in categories)
            {
                if (cat.Children.Count > 0)
                {
                    ProductGroupFilter groupFilter = new ProductGroupFilter();
                    groupFilter.Category = cat;
                    if (Locator.GetService<IProductGroupManager>().Count(groupFilter) > 0)
                    {
                        NavigationItem navigation = ConvertToNavigation(cat);
                        if (navigation != null)
                            ret.Add(navigation);
                    }
                }
            }
            return ret;
        }

        public NavigationItem ConvertToNavigation(Category cat)
        {
            NavigationItem ret = null;
            ret = new NavigationItem(cat.Name, cat.Id.ToString());
            NavigationItem[] childrenNavigation = new NavigationItem[cat.Children.Count];
            int i = 0;
            foreach (Category category in cat.Children)
            {
                childrenNavigation[i] = new NavigationItem(category.Seo, category.Name, category.Id.ToString());
                i++;
            }
            ret.Childrens = childrenNavigation;
            return ret;
        }
    }
}